package org.example.xsda.service;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.example.xsda.dto.LoginDTO;
import org.example.xsda.dto.RegisterDTO;
import org.example.xsda.entity.Student;
import org.example.xsda.entity.SysRole;
import org.example.xsda.entity.SysUser;
import org.example.xsda.exception.BusinessException;
import org.example.xsda.mapper.StudentMapper;
import org.example.xsda.mapper.SysRoleMapper;
import org.example.xsda.mapper.SysUserMapper;
import org.example.xsda.util.PasswordUtil;
import org.example.xsda.vo.LoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 认证服务
 */
@Slf4j
@Service
public class AuthService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private RedisService redisService;

    // 缓存key前缀
    private static final String CACHE_KEY_ROLE = "role:";

    /**
     * 用户登录（带角色缓存）
     */
    public LoginVO login(LoginDTO loginDTO) {
        // 查询用户
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, loginDTO.getUsername());
        SysUser user = sysUserMapper.selectOne(wrapper);

        if (user == null) {
            throw new BusinessException("用户名或密码错误");
        }

        // 校验密码
        if (!PasswordUtil.verify(loginDTO.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        // 校验用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException("账号已被禁用，请联系管理员");
        }

        // 查询角色信息（带缓存）
        SysRole role = getRoleById(user.getRoleId());
        if (role == null) {
            throw new BusinessException("用户角色不存在");
        }

        // 执行登录
        StpUtil.login(user.getId());
        // 将角色信息存入Session
        StpUtil.getSession().set("roleCode", role.getRoleCode());
        StpUtil.getSession().set("roleName", role.getRoleName());

        // 获取token
        String token = StpUtil.getTokenValue();

        // 构建返回结果
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(token);
        loginVO.setUserId(user.getId());
        loginVO.setUsername(user.getUsername());
        loginVO.setRealName(user.getRealName());
        loginVO.setRoleCode(role.getRoleCode());
        loginVO.setRoleName(role.getRoleName());
        // 如果字段为null，默认为1（需要修改密码），更安全
        loginVO.setNeedChangePassword(user.getNeedChangePassword() != null ? user.getNeedChangePassword() : 1);

        // 如果是学生角色，查询信息完善状态
        if ("student".equals(role.getRoleCode())) {
            LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
            studentWrapper.eq(Student::getUserId, user.getId());
            Student student = studentMapper.selectOne(studentWrapper);
            if (student != null) {
                loginVO.setInfoCompleted(student.getInfoCompleted() != null ? student.getInfoCompleted() : 0);
            } else {
                loginVO.setInfoCompleted(0);
            }
        } else {
            loginVO.setInfoCompleted(1); // 非学生角色默认已完善
        }

        log.info("用户登录成功：{}, 需要修改密码: {}, 信息完善: {}", 
                user.getUsername(), loginVO.getNeedChangePassword(), loginVO.getInfoCompleted());
        return loginVO;
    }

    /**
     * 用户注册
     */
    public void register(RegisterDTO registerDTO) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, registerDTO.getUsername());
        Long count = sysUserMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException("用户名已存在");
        }

        // 检查角色是否存在
        SysRole role = sysRoleMapper.selectById(registerDTO.getRoleId());
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 创建用户
        SysUser user = new SysUser();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(PasswordUtil.encrypt(registerDTO.getPassword()));
        user.setRealName(registerDTO.getRealName());
        user.setRoleId(registerDTO.getRoleId());
        user.setPhone(registerDTO.getPhone());
        user.setStatus(1);

        sysUserMapper.insert(user);
        log.info("用户注册成功：{}", user.getUsername());
    }

    /**
     * 退出登录
     */
    public void logout() {
        StpUtil.logout();
        log.info("用户退出登录");
    }
    
    /**
     * 根据ID获取角色（带缓存）
     */
    private SysRole getRoleById(Long roleId) {
        String cacheKey = CACHE_KEY_ROLE + roleId;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取角色信息：roleId={}", roleId);
            return (SysRole) cached;
        }
        
        // 缓存未命中，从数据库查询
        SysRole role = sysRoleMapper.selectById(roleId);
        if (role != null) {
            // 存入缓存（2小时，角色信息变化不频繁）
            redisService.set(cacheKey, role, 2, java.util.concurrent.TimeUnit.HOURS);
            log.debug("将角色信息存入缓存：roleId={}", roleId);
        }
        
        return role;
    }
}

